#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include <unistd.h>

#define NUM_THREADS 2       // 线程数
#define NUM_TESTS 50000      // 每个线程执行的操作次数

sem_t semaphore1, semaphore2;          // 信号量

double total_time = 0.0;  // 记录总时间
pthread_mutex_t time_lock = PTHREAD_MUTEX_INITIALIZER;  // 用于保护 total_time 变量的锁

void *test_semaphore_A(void *arg) {
    printf("satrt A\n");
    int i;
    for (i = 0; i < NUM_TESTS; i++) {
    sem_wait(&semaphore1);
    sem_post(&semaphore2);
     }

    
}
void *test_semaphore_B(void *arg) {
    int i;
    struct timespec start_time, end_time;
    printf("satrtB\n");
    for (i = 0; i < NUM_TESTS; i++) {
        clock_gettime(CLOCK_MONOTONIC, &start_time);
        sem_post(&semaphore1);
        sem_wait(&semaphore2);
        clock_gettime(CLOCK_MONOTONIC, &end_time);
                // 计算操作耗时（秒为单位）
        double elapsed_time = (end_time.tv_sec - start_time.tv_sec) +
                              (end_time.tv_nsec - start_time.tv_nsec) /1.0e3;

        // // 更新总时间
        pthread_mutex_lock(&time_lock);  // 锁住 total_time
        total_time += elapsed_time;
        pthread_mutex_unlock(&time_lock);  // 解锁 total_time
    }
    return NULL;

}

int main() {
    pthread_t task_A, task_B;  // 线程句柄
    int i;
    printf("satrt\n");

    // 初始化信号量，值为 1
    if (sem_init(&semaphore1, 0, 1) != 0) {
        perror("sem_init failed");
        exit(1);
    }
    if (sem_init(&semaphore2, 0, 1) != 0) {
        perror("sem_init failed");
        exit(1);
    }
    // 创建线程
    if (pthread_create(&task_A, NULL, test_semaphore_A, NULL) != 0) {
        perror("pthread_create failed");
        exit(1);
    }
    if (pthread_create(&task_B, NULL, test_semaphore_B, NULL) != 0) {
        perror("pthread_create failed");
        exit(1);
    }
    // 等待所有线程完成
    if (pthread_join(task_A, NULL) != 0) {
        perror("pthread_join failed");
        exit(1);
    }
    if (pthread_join(task_B, NULL) != 0) {
        perror("pthread_join failed");
        exit(1);
    }


    // 计算并输出平均混洗时间
    double avg_time = total_time / (NUM_THREADS * NUM_TESTS);
    printf("avg_time:%.3fus\n", avg_time);

    // 销毁信号量
    sem_destroy(&semaphore1);
    sem_destroy(&semaphore2);

    return 0;
}

